#include<iostream>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<random>
#define N 500001
#define M 10000000
#define W 65535
#define Z 16777215
using namespace std;
mt19937 RAND(random_device{}());
int read()
{
	char c=0;
	int sum=0;
	while (c<'0'||c>'9') c=getchar();
	while ('0'<=c&&c<='9') sum=sum*10+c-'0',c=getchar();
	return sum;
}
void write(__int128 x)
{
	if (0<=x&&x<=9)
	{
		printf("%d",(int)(x));
		return;
	}
	write(x/10),printf("%d",(int)(x%10));
	return;
}
int gcd(int x,int y)
{
	if (!y) return x;
	return gcd(y,x%y);
}
int lcm(int x,int y)
{
	return x/gcd(x,y)*y;
}
int n,q,p,sx,sy,len,slen[N+1],rd[W+1],rd2[W+1],rd3[W+1],rd4[W+1],tong[N+1],length,kr[N+1],kp[N+1],kd[N+1],head[Z+1],a[N+1],b[N+1],wcnt[N+1],tr,tp;
bool op;
struct reads
{
	int zr,zp,data;
};
vector<reads>p1[N+1];
vector<reads>p2[N+1];
struct node
{
	int x,y;
	long long data;
	__int128 data2;
	int nxt;
};
node edge[M+1];
void adder_hsh(int x,int y,int d)
{
	int ds=rd[x&W]^rd2[x>>16]^rd3[y&W]^rd4[y>>16];
	for (int i=head[ds];i>0;i=edge[i].nxt)
		if (edge[i].x==x&&edge[i].y==y)
		{
			edge[i].data+=d;
			return;
		}
	edge[++len]=(node){x,y,d,0,head[ds]},head[ds]=len;
	return;
}
void adder_hsh2(int x,int y,long long d)
{
	int ds=rd[x&W]^rd2[x>>16]^rd3[y&W]^rd4[y>>16];
	for (int i=head[ds];i>0;i=edge[i].nxt)
		if (edge[i].x==x&&edge[i].y==y)
		{
			edge[i].data2+=d;
			return;
		}
	edge[++len]=(node){x,y,0,d,head[ds]},head[ds]=len;
	return;
}
long long query_hsh(int x,int y)
{
	int ds=rd[x&W]^rd2[x>>16]^rd3[y&W]^rd4[y>>16];
	for (int i=head[ds];i>0;i=edge[i].nxt)
		if (edge[i].x==x&&edge[i].y==y)
			return edge[i].data;
	return 0;
}
__int128 query_hsh2(int x,int y)
{
	int ds=rd[x&W]^rd2[x>>16]^rd3[y&W]^rd4[y>>16];
	for (int i=head[ds];i>0;i=edge[i].nxt)
		if (edge[i].x==x&&edge[i].y==y)
			return edge[i].data2;
	return 0;
}
void exgcd(int x,int y)
{
	if (!y)
	{
		sx=1,sy=0;
		return;
	}
	exgcd(y,x%y);
	int zx=sx;
	sx=sy,sy=zx-x/y*sy;
	return;
}
int get_inv(int x,int sp)
{
	exgcd(x,sp);
	return (sx%sp+sp)%sp;
}
void insert(int x,int sp)
{
	if (sp==tp)
	{
		if (tr!=x) op=1;
		return;
	}
	if ((x-tr)%gcd(tp,sp)!=0)
	{
		op=1;
		return;
	}
	int ds=(x-tr)/gcd(tp,sp),wp=lcm(tp,sp);
	exgcd(tp,sp),sx=(sx%sp+sp)%sp;
	long long dz=1ll*(1ll*sx*ds%wp)*tp+tr;
	tr=(dz%wp+wp)%wp,tp=wp;
	return;
}
void append(int x,int y)
{
	int d=gcd(x,p),sp;
	if (y%d!=0)
	{
		op=1;
		return;
	}
	x/=d,y/=d,sp=p/d,insert(1ll*y*get_inv(x,sp)%sp,sp);
	return;
}
void adder(int x)
{
	if (p1[x].empty()||p1[x].back().zp!=tp) p1[x].push_back((reads){tr,tp,1});
	else p1[x].back().data++;
	return;
}
void adder2(int x)
{
	if (p2[x].empty()||p2[x].back().zp!=tp) p2[x].push_back((reads){tr,tp,1});
	else p2[x].back().data++;
	return;
}
void solve()
{
	int g,g2,d,dr,wp,ps=0,rst;
	for (int i=1;i<=n;++i)
	{
		op=0;
		if (ps+slen[ps]>=i)
		{
			p1[i]=p1[(ps<<1)-i],slen[i]=min(slen[(ps<<1)-i],ps+slen[ps]-i),rst=slen[(ps<<1)-i]-slen[i];
			while (rst)
			{
				d=min(p1[i].back().data,rst),p1[i].back().data-=d,rst-=d;
				if (!p1[i].back().data) p1[i].pop_back();
			}
			tr=p1[i].back().zr,tp=p1[i].back().zp;
		}
		else tr=0,tp=1,adder(i);
		while (slen[i]+1<=min(i-1,n-i))
		{
			append((a[i-slen[i]-1]-a[i-slen[i]]+p)%p,(a[i+slen[i]+1]-a[i+slen[i]]+p)%p);
			if (op) break;
			append((a[i+slen[i]+1]-a[i+slen[i]]+p)%p,(a[i-slen[i]-1]-a[i-slen[i]]+p)%p);
			if (op) break;
			slen[i]++,adder(i);
		}
		if (i+slen[i]>ps+slen[ps]) ps=i;
	}
	ps=0;
	for (int i=1;i<=n-1;++i)
	{
		slen[i]=-1,op=0;
		if (ps+slen[ps]>=i)
		{
			p2[i]=p2[(ps<<1)-i],slen[i]=min(slen[(ps<<1)-i],ps+slen[ps]-i),rst=slen[(ps<<1)-i]-slen[i];
			while (rst)
			{
				d=min(p2[i].back().data,rst),p2[i].back().data-=d,rst-=d;
				if (!p2[i].back().data) p2[i].pop_back();
			}
			tr=p2[i].back().zr,tp=p2[i].back().zp;
		}
		else
		{
			tr=0,tp=1,append((a[i]-a[i+1]+p)%p,(a[i+1]-a[i]+p)%p);
			if (op) continue;
			slen[i]=0,adder2(i);
		}
		while (slen[i]+1<=min(i-1,n-i-1))
		{
			append((a[i-slen[i]-1]-a[i-slen[i]]+p)%p,(a[i+slen[i]+2]-a[i+slen[i]+1]+p)%p);
			if (op) break;
			append((a[i+slen[i]+2]-a[i+slen[i]+1]+p)%p,(a[i-slen[i]-1]-a[i-slen[i]]+p)%p);
			if (op) break;
			slen[i]++,adder2(i);
		}
		if (i+slen[i]>ps+slen[ps]) ps=i;
	}
	for (int i=1;i<=n;++i)
		for (int j=0;j<p1[i].size();++j)
			adder_hsh(p1[i][j].zp,p1[i][j].zr,p1[i][j].data);
	for (int i=1;i<=n-1;++i)
		for (int j=0;j<p2[i].size();++j)
			adder_hsh(p2[i][j].zp,p2[i][j].zr,p2[i][j].data);
	for (int i=1;i<=n;++i)
	{
		for (int j=0;j<p1[i].size();++j) g=gcd(a[i],p),wp=p/g,g2=gcd(wp,p1[i][j].zp),dr=(1ll*(a[i]/g)*(1-p1[i][j].zr)%g2+g2)%g2,kr[j]=dr*g,kp[j]=g*g2,kd[j]=p/lcm(wp,p1[i][j].zp);
		for (int j=0;j<p1[i].size();++j) adder_hsh2(kp[j],kr[j],1ll*p1[i][j].data*kd[j]);
	}
	for (int i=1;i<=n-1;++i)
	{
		for (int j=0;j<p2[i].size();++j) g=gcd(a[i],p),wp=p/g,g2=gcd(wp,p2[i][j].zp),dr=(1ll*(a[i]/g)*p2[i][j].zr%g2+g2)%g2,kr[j]=((a[i+1]-dr*g)%(g*g2)+(g*g2))%(g*g2),kp[j]=g*g2,kd[j]=p/lcm(wp,p2[i][j].zp);
		for (int j=0;j<p2[i].size();++j) adder_hsh2(kp[j],kr[j],1ll*p2[i][j].data*kd[j]);
	}
	return;
}
long long query(int x)
{
	long long res=0;
	for (int i=1;i<=length;++i) res+=query_hsh(tong[i],x%tong[i]);
	return res;
}
__int128 query2(int x)
{
	__int128 res=0;
	for (int i=1;i<=length;++i) res+=query_hsh2(tong[i],x%tong[i]);
	return res;
}
int main()
{
	//freopen("string.in","r",stdin);
	//freopen("string.out","w",stdout);
	int op,x;
	for (int i=0;i<W;++i) rd[i]=RAND()&Z,rd2[i]=RAND()&Z,rd3[i]=RAND()&Z,rd4[i]=RAND()&Z;
	n=read(),q=read(),p=read();
	for (int i=1;i*i<=p;++i)
		if (p%i==0)
		{
			tong[++length]=i;
			if (i*i!=p) tong[++length]=p/i;
		}
	for (int i=1;i<=n;++i) a[i]=read();
	solve();
	while (q--)
	{
		op=read(),x=read();
		if (op==1) printf("%lld\n",query(x));
		else write(query2(x)),puts("");
	}
	return 0;
}
